---@class RedRob.SceneMgr
local SceneMgr = RedRob.CreateSingleton("SceneMgr")
local this = SceneMgr
function SceneMgr.OnCreate()
    this.isLoading = false
    this.gRoot = nil
    ---@type Transform
    this.sceneRoot = nil
    ---@type BoxCollider
    this.boxCollider = nil
    this.cameraTran = nil
    ---@type Camera
    this.camera = nil
    ---@type Transform
    this.effectRoot = nil
    ---@type Transform
    this.poolRoot = nil
end
function SceneMgr.OnDestroy()
    this.isLoading = false
    if this.gRoot then
        destroy(this.gRoot)
    end
    this.gRoot = nil
    this.sceneRoot = nil
    this.cameraTran = nil
    this.camera = nil
    this.boxCollider = nil
end
function SceneMgr.AddChild(transform)
    if this.sceneRoot == nil then
        logError("[AddChild]场景未创建，无法添加")
        return
    end
    if transform then
        transform:SetParent(this.sceneRoot,false)
    end
end
function SceneMgr.AddEffectChild(transform)
    if this.effectRoot == nil then
        logError("[AddEffectChild]场景未创建，无法添加")
        return
    end
    if transform then
        transform:SetParent(this.effectRoot,false)
    end
end
function SceneMgr.AddPoolChild(transform)
    if this.poolRoot == nil then
        logError("[AddPoolChild]场景未创建，无法添加")
        return
    end
    if transform then
        transform:SetParent(this.poolRoot,false)
    end
end
function SceneMgr.LoadScene(path,callback)
    if this.isLoading then
        return
    end
    this.isLoading = true
    resMgr:LoadMapPrefab(path,function(obj)
        if this.gRoot then
            return
        end
        local go = newObject(obj)
        this.LoadSceneDone(go,callback)
    end)
    --local name = "Prefabs/MapPref/AutoFightMap21"

end
function SceneMgr.LoadSceneDone(go,callback)
    this.gRoot = go
    local b = go.transform:Find("Map")
    if b then
        b.gameObject:SetActive(false)
    end
    local root = go.transform:Find("BattleMap")
    local temp = GameObject.New("root")
    this.sceneRoot = temp.transform
    this.sceneRoot:SetParent(root,false)
    temp = GameObject.New("effect")
    this.effectRoot = temp.transform
    this.effectRoot:SetParent(root,false)
    temp = GameObject.New("pool")
    this.poolRoot = temp.transform
    this.poolRoot:SetParent(root,false)
    this.AddBoxCollider()
    local pos = RedRob.ClientBattle.SCENE_ORIGIN_POS
    local rotX = RedRob.ClientBattle.SCENE_ORIGIN_ROTATE_X
    Util.Lua_SetLocalPositionXYZ(this.sceneRoot,pos.x,pos.y,pos.z)
    Util.Lua_SetLocalRotationXYZ(this.sceneRoot,rotX,0,0)
    Util.Lua_SetLocalPositionXYZ(this.effectRoot,pos.x,pos.y,pos.z)
    Util.Lua_SetLocalRotationXYZ(this.effectRoot,rotX,0,0)

    --this.farList = {this.MapItem.New(root:GetChild(0))}
    --this.midList = {this.MapItem.New(root:GetChild(1))}
    --this.nearList = {this.MapItem.New(root:GetChild(2))}
    this.LoadDone()
    if callback then
        callback()
    end
end
function SceneMgr.AddBoxCollider()
    if this.boxCollider then
        return
    end
    this.boxCollider = this.sceneRoot.gameObject:AddComponent(TBoxCollider)
    local bat = RedRob.ClientBattle
    local width = bat.GetMaxX()-bat.GetMinX()
    local height = 30--bat.GetMaxY()- bat.GetMinY()
    local vec3 = Vector3.GetCacheVec():Set(width,height,0.01)
    this.boxCollider.size = vec3
    this.boxCollider.center = vec3:Set(width/2,height/2,1)
    Vector3.ReturnToPool(vec3)
end
---world pos -> local pos
---@return number,number,number
function SceneMgr.InverseTransformPoint(wx,wy,wz)
    local x,y,z = Util.InverseTransformPoint(this.sceneRoot,wx,wy,wz,0,0,0)
    return x,y,z--this.sceneRoot:InverseTransformPoint(wPos.x,wPos.y,wPos.z)
end
---local pos -> world pos
---@return number,number,number
function SceneMgr.TransformPoint(lx,ly,lz)
    local x,y,z = Util.TransformPoint(this.sceneRoot,lx,ly,lz,0,0,0)
    return x,y,z--this.sceneRoot:TransformPoint(lPos.x,lPos.y,lPos.z)
end
function SceneMgr.LoadDone()
    Util.Lua_SetLocalPositionXYZ(this.gRoot,-1500,-1500,0);
    this.CreateCamera()
    --this.ExpandScene()
end

function SceneMgr.CreateCamera()
    local go = GameObject.New("camera")
    ---@type UnityEngine.Camera
    local camera = go:AddComponent(TCamera)
    camera.depth = -1
    camera.orthographic = true
    camera.orthographicSize = 11
    camera.farClipPlane = 300
    local tran = camera.transform
    this.cameraTran = tran
    this.camera = camera
    tran:SetParent(this.sceneRoot,false)
    Util.Lua_SetLocalPositionXYZ(this.cameraTran,0,0,-10);
    Util.Lua_SetLocalRotationXYZ(this.cameraTran,0,0,0)
    RedRob.CameraController.SetCamera(camera)
end
--相机出屏，循环场景
function SceneMgr.ExpandScene()
    this.DoExpandScene(this.nearList)
    this.DoExpandScene(this.farList)
    this.DoExpandScene(this.midList)

end
function SceneMgr.DoExpandScene(mapItems)
    while true do
        local mapItem = mapItems[#mapItems]
        local endPos = mapItem.endPos
        local startPos = mapItem.startPos
        local screeWidth = Screen.width
        local mapItemTran = mapItem.go.transform
        local mapItemPos = mapItemTran.localPosition
        local point = this.camera:WorldToScreenPoint(mapItem:GeEndWPos())
        if point.x < screeWidth then
            local tran
            if#mapItems == 1 then
                local go = newObject(mapItem.go)
                tran = go.transform
                tran:SetParent(mapItemTran.parent,false)
                mapItemPos.x = mapItemPos.x + endPos.x - startPos.x
                Util.Lua_SetLocalPositionXYZ(tran,mapItemPos.x,mapItemPos.y,mapItemPos.z);
                table.insert(mapItems,MapItem.New(go))
            else
                local nextItem = mapItems[1]
                mapItemPos.x = mapItemPos.x + endPos.x - startPos.x
                Util.Lua_SetLocalPositionXYZ(nextItem.go.transform,mapItemPos.x,mapItemPos.y,mapItemPos.z);
                mapItems[1] = mapItem
                mapItems[2] = nextItem
            end
        else
            break
        end
    end
    this.DoExpandSceneLeft(mapItems)
end
function SceneMgr.DoExpandSceneLeft(mapItems)
    while true do
        local mapItem = mapItems[1]
        local endPos = mapItem.endPos
        local startPos = mapItem.startPos
        local mapItemTran = mapItem.go.transform
        local mapItemPos = mapItemTran.localPosition
        local point = this.camera:WorldToScreenPoint(mapItem:GeStartWPos())
        if point.x > 0 then
            local tran
            if#mapItems == 1 then
                local go = newObject(mapItem.go)
                tran = go.transform
                tran:SetParent(mapItemTran.parent,false)
                mapItemPos.x = mapItemPos.x -(endPos.x - startPos.x)
                Util.Lua_SetLocalPositionXYZ(tran,mapItemPos.x,mapItemPos.y,mapItemPos.z);
                table.insert(mapItems,1,MapItem.New(go))
            else
                local nextItem = mapItems[2]
                mapItemPos.x = mapItemPos.x - (endPos.x - startPos.x)
                Util.Lua_SetLocalPositionXYZ(nextItem.go.transform,mapItemPos.x,mapItemPos.y,mapItemPos.z);
                mapItems[1] = nextItem
                mapItems[2] = mapItem
            end
        else
            break
        end
    end
end




SceneMgr.MapItem = Class("")
function SceneMgr.MapItem:ctor(obj)
    self.go = obj

    self.endTran = obj.transform:Find("EndPoint")
    self.startTran = obj.transform:Find("StartPoint")
    self.startPos = self.startTran.localPosition
    self.endPos = self.endTran.localPosition
end
function SceneMgr.MapItem:GeEndWPos()
    return self.endTran.position
end
function SceneMgr.MapItem:GeStartWPos()
    return self.startTran.position
end
